Creating and Combining Views — SwiftUI Tutorials | Apple Developer Documentation
创建新项目并使用cavans
新建项目
ContentView.swift 文件内容如下:
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
默认情况下,SwiftUI视图文件声明两个结构体。
- 第一个结构符合View协议,描述了视图的内容和布局。
- 第二个结构声明该视图的预览。
定制TextView
您可以通过更改代码来自定义视图的显示,或者使用检查器(inspector)来发现可用的内容并辅助编写代码。
如何使用inspector
- 编辑区,command+左键, 点击组件
- 选择:
Show SwiftUI Inspector
可以将Text字体改成Title:效果将会展示系统字体,并且它会正确响应用户手机设计的字体大小和设置。
modifiers
要自定义SwiftUI视图,可以调用称被为modifiers的方法。modifiers包裹视图以更改其显示或其他属性。每个modifier返回new view,因此可以使用链式语法。
struct ContentView: View {
var body: some View {
VStack {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.cyan)
}
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.cyan)
}
}
}
使用Stacks组合视图
在上面的操作中,我们增加了标题,现在看看如何增加一行详情:展示公园名称和所在州。
当创建SwiftUI视图时,您在视图的body属性中描述其内容、布局和行为;但是,body属性只返回一个视图。为了解决这个问题,我们可以将多个视图组合并嵌入到stack中,stack将视图以horizontally、vertically 或者 back-to-front的方式组合在一起。
将视图嵌入VStack:
增加一个text组件:
修改VStack的alignment为.leading
,将文字改为了左对齐:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.cyan)
Text("Joshua Tree National Park")
.font(.subheadline)
}
}
}
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
.foregroundColor(.cyan)
Text("Joshua Tree National Park")
.font(.subheadline)
}
}
}
增加展示公园所在的州:
- 先将公园名称控件嵌入HStack
- 增加text展示州
- 使用spacer撑开中间空间
关于Spacer():
- Spacer会自动撑开以便其所在的视图使用其父视图中的全部空间,而不仅仅是由其内容定义的大小
使用padding增加默认间距,将视图展示得更美观一些:
定制Image View
前置工作:
- 在工程Assets里面增加一张图片,名称为
turtlerock@2x.jpg
- 新建一个Swiftui文件,名称为CircleImage.swift
使用clipShape修饰器可以将图片切成我们需要的形状:
创建另一个带有灰色描边的圆,然后将其添加为图片的overlay,为图像提供边框。
使用shadow增加阴影:
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay {
Circle().stroke(.red, lineWidth: 5)
}
// add shadow
.shadow(radius: 7)
}
}
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay {
Circle().stroke(.red, lineWidth: 5)
}
// add shadow
.shadow(radius: 7)
}
}
在其他框架中使用SwiftUI
接下来,您将创建一个以给定坐标为中心的贴图。您可以使用MapKit中的Map视图来呈现地图。
import SwiftUI
import MapKit
struct MapView: View {
// 创建保存地图区域信息的私有状态变量。
// 你可以使用@State属性来修饰数据源,这样你可以从多个视图中修改数据。 当数据源改变SwiftUI会根据值的变化动态更新依赖该值的视图
@State
private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
var body: some View {
// 通过给状态变量加上前缀$,传递了一个绑定,就像是对底层值的引用。当用户与地图交互时,地图更新区域值以匹配用户界面中当前可见的地图部分。
// Binding<MKCoordinateRegion>
Map(coordinateRegion: $region)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
import SwiftUI
import MapKit
struct MapView: View {
// 创建保存地图区域信息的私有状态变量。
// 你可以使用@State属性来修饰数据源,这样你可以从多个视图中修改数据。 当数据源改变SwiftUI会根据值的变化动态更新依赖该值的视图
@State
private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
var body: some View {
// 通过给状态变量加上前缀$,传递了一个绑定,就像是对底层值的引用。当用户与地图交互时,地图更新区域值以匹配用户界面中当前可见的地图部分。
// Binding<MKCoordinateRegion>
Map(coordinateRegion: $region)
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
编写详情视图
接下来实现将MapView、Image View集成到Content.swift页面里面。
MapView:
- 如果仅指定height参数,则视图将自动调整大小为其内容的宽度(VStack中)。在这种情况下,MapView将展开以填充可用空间。
如果要忽略安全区域,可以使用ignoresSafeArea
MapView()
.ignoresSafeArea(edges: .top)
.frame(height: 300)
MapView()
.ignoresSafeArea(edges: .top)
.frame(height: 300)